<?
	include_once('DbBridge.php');
	class DbManager {
		var $errors = array();

		public function getErrors () { return $this->errors; }

		public function getUserById ($db, $id) {
			$dbValidationError = $this->validateDbBridge($db);
			if ($dbValidationError) {
				return $this->pushError("DbManager::getUserById parameter 'db': ".$dbValidationError) && false;
			}
			$idValidationError = $this->validateUserId($id);
			if ($idValidationError) {
				return $this->pushError("DbManager::getUserById parameter 'id': ".$idValidationError) && false;
			}
			$queryResult = $db->query("SELECT * FROM user WHERE id=".$id);
			if (!$queryResult) {
				return $this->pushError("DbManager::getUserById query returned error") && false;
			}
			$queryResultLength = $db->getCount($queryResult);
			if ($queryResultLength == 0) {
				return $this->pushError("DbManager::getUserById can not find user with id=".$id) && false;
			}
			if ($queryResultLength > 1) {
				return $this->pushError("DbManager::getUserById DB ERROR: found more than one user with id=".$id) && false;
			}
			$rows = $db->getRows($queryResult);
			$user = current($rows);
			return $user;
		}
		public function getUserByVkId ($db, $vkId) {
			$dbValidationError = $this->validateDbBridge($db);
			if ($dbValidationError) {
				return $this->pushError("DbManager::getUserByVkId parameter 'db': ".$dbValidationError) && false;
			}
			$vkIdValidationError = $this->validateUserVkId($vkId);
			if ($vkIdValidationError) {
				return $this->pushError("DbManager::getUserByVkId parameter 'vkId': ".$vkIdValidationError) && false;
			}
			$queryResult = $db->query("SELECT * FROM user WHERE vk_id=".$vkId);
			if (!$queryResult) {
				return $this->pushError("DbManager::getUserByVkId PROGRAM ERROR: query returned error") && false;
			}
			$queryResultLength = $db->getCount($queryResult);
			if ($queryResultLength == 0) {
				return $this->pushError("DbManager::getUserByVkId can not find user with vk_id=".$vkId) && false;
			}
			if ($queryResultLength > 1) {
				return $this->pushError("DbManager::getUserByVkId DB ERROR: found more than one user with vk_id=".$vkId) && false;
			}
			$rows = $db->getRows($queryResult);
			$user = current($rows);
			return $user;
		}
		public function updateUser ($db, $user) {
			$dbValidationError = $this->validateDbBridge($db);
			if ($dbValidationError) {
				return $this->pushError("DbManager::updateUser parameter 'db': ".$dbValidationError) && false;
			}
			$userValidationError = $this->validateUserArray($user);
			if ($userValidationError) {
				$this->pushError("DbManager::updateUser parameter 'user' is invalid: ".$userValidationError);
				return false;
			}
			$updateQueryString = $this->getUpdateQueryString($user);
			$queryResult = $db->query($updateQueryString);
			if (!is_bool($queryResult)) {
				$this->pushError("DbManager::updateUser strange query result: not bool");
				return false;
			}
			if (!$queryResult) {
				$error = end($db->getErrors());
				$this->pushError("DbManager::updateUser see db error: ".$error." Query: ".$updateQueryString);
				return false;
			}
			return $queryResult;
		}
		public function userExistsById ($db, $id) {
			$dbValidationError = $this->validateDbBridge($db);
			if ($dbValidationError) {
				$this->pushError("DbManager::userExistsById parameter 'db': ".$dbValidationError);
				return 'error';
			}
			$idValidationError = $this->validateUserId($id);
			if ($idValidationError) {
				$this->pushError("DbManager::userExistsById parameter 'id': ".$idValidationError);
				return 'error';
			}
			$queryResult = $db->query("SELECT id FROM user WHERE id=".$id);
			if (!$queryResult) {
				$this->pushError("DbManager::userExistsById see db error");
				return 'error';
			}
			$queryResultLength = $db->getCount($queryResult);
			return $queryResultLength > 0;
		}
		public function userExistsByVkId ($db, $vkId) {
			$dbValidationError = $this->validateDbBridge($db);
			if ($dbValidationError) {
				$this->pushError("DbManager::userExistsByVkId parameter 'db': ".$dbValidationError);
				return 'error';
			}
			$vkIdValidationError = $this->validateUserVkId($vkId);
			if ($vkIdValidationError) {
				$this->pushError("DbManager::userExistsByVkId parameter 'vkId': ".$vkIdValidationError);
				return 'error';
			}
			$queryResult = $db->query("SELECT id FROM user WHERE vk_id=".$vkId);
			if (!$queryResult) {
				$this->pushError("DbManager::userExistsById see db error");
				return 'error';
			}
			$queryResultLength = $db->getCount($queryResult);
			return $queryResultLength > 0;
		}
		public function newUser ($db, $vkId) {
			$dbValidationError = $this->validateDbBridge($db);
			if ($dbValidationError) {
				return $this->pushError("DbManager::newUser parameter 'db': ".$dbValidationError) && false;
			}
			$vkIdValidationError = $this->validateUserVkId($vkId);
			if ($vkIdValidationError) {
				return $this->pushError("DbManager::newUser parameter 'vkId': ".$vkIdValidationError) && false;
			}
			if ($this->userExistsByVkId($db, $vkId)) {
				return $this->pushError("DbManager::newUser user with vkId=".$vkId." already exists") && false;
			}
			$insertQueryString = 
				"INSERT INTO user (
					id, vk_id, bonus_time, money_count, loupe_scale, hint_radius, level, money_bought, money_spent, achievement) 
				VALUES (NULL, '".$vkId."', '10', '0', '1.2', '100', '1', '0', '0', '0');";
			$queryResult = $db->query($insertQueryString);
			if (!$queryResult) {
				$this->pushError("DbManager::newUser error while executing insert query");
				return false;
			}
			return $queryResult;
		}

		private function getUpdateQueryString ($user) {
			$bonusTime = $user['bonus_time'];
			$moneyCount = $user['money_count'];
			$loupeScale = $user['loupe_scale'];
			$hintRadius = $user['hint_radius'];
			$level = $user['level'];
			$moneyBought = $user['money_bought'];
			$moneySpent = $user['money_spent'];
			$vkId = $user['vk_id'];
			$achievement = empty($user['achievement']) ? 0 : $user['achievement'];
			return "UPDATE user SET bonus_time=".$bonusTime.", money_count=".$moneyCount.", loupe_scale=".$loupeScale.", level=".$level.", money_bought=".$moneyBought.", money_spent=".$moneySpent.", achievement=".$achievement." WHERE vk_id=".$vkId;
		}
		private function pushError ($error) { array_push($this->errors, $error); }

		private function validateUserArray ($user) {
			if (!$user) {
				return "is not set";
			}
			if (!is_array($user)) {
				return "is not an array";
			}
			// if (array_key_exists('id', $user)) {
			// 	return "does not contains key 'id'";
			// }
			if (array_key_exists('"vk_id"', $user)) {
				$this->pushError(json_encode($user));
				return "does not contains key 'vk_id'";
			}
			if (array_key_exists('"bonus_time"', $user)) {
				return "does not contains key 'bonus_time'";
			}
			if (array_key_exists('"money_count"', $user)) {
				return "does not contains key 'money_count'";
			}
			if (array_key_exists('"loupe_scale"', $user)) {
				return "does not contains key 'loupe_scale'";
			}
			if (array_key_exists('"hint_radius"', $user)) {
				return "does not contains key 'hint_radius'";
			}
			if (array_key_exists('"level"', $user)) {
				return "does not contains key 'level'";
			}
			if (array_key_exists('"money_bought"', $user)) {
				return "does not contains key 'money_bought'";
			}
			if (array_key_exists('"money_spent"', $user)) {
				return "does not contains key 'money_spent'";
			}
			if (array_key_exists('"achievement"', $user)) {
				return "does not contains key 'achievement'";
			}
			return false;
		}
		private function validateDbBridge ($db) {
			if (!$db) {
				return "is not set";
			}
			if (!is_object($db) || (get_class($db) != 'DbBridge')) {
				return "is not DbBridge";
			}
			return false;
		}
		private function validateUserId ($id) {
			if (!$id) {
				return "is not set";
			}
			if (!is_int($id) && !is_numeric($id)) {
				return "is not int";
			}
			return false;
		}
		private function validateUserVkId ($vkId) {
			if (!$vkId) {
				return "is not set";
			}
			if (!is_int($vkId) && !is_numeric($vkId)) {
				return "is not int";
			}
			return false;
		}
	}
?>